/* 
 * Copyright (C) 2011, WordCards4Me Project - http://code.google.com/p/wordcards4me/
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.wordcards4me;

import java.io.InputStreamReader;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Stack;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Image;
import javax.microedition.midlet.MIDlet;

public class CardMidlet extends MIDlet {

	private static Vector listeners = new Vector();
	private static Hashtable settings = new Hashtable();
	private static Stack screens = new Stack();

	private static Display display;

	public CardMidlet() {
		display = Display.getDisplay(this);
	}

	public void startApp() {
		if (isSupportFileConnectionAPI()) {
			loadDefaultProperties();
			goForward(new MenuScreen(this));
		}
	}

	public void pauseApp() {
		notifyPaused();
	}

	public void destroyApp(boolean cond) {
		notifyDestroyed();
	}

	public void exit() {
		destroyApp(false);
		notifyDestroyed();
	}

	private boolean isSupportFileConnectionAPI() {
		return System.getProperty("microedition.io.file.FileConnection.version") != null;
	}

	/**
	 * This method loads image from specified path.
	 */
	public static Image loadImage(String filename) {
		Image image = null;
		try {
			image = Image.createImage(filename);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return image;
	}

	public static void goBackward() {
		screens.pop();
		Object o = screens.peek();
		display.setCurrent((Displayable) o);
	}

	public static void goForward(Displayable next) {
		if (next != null) {
			screens.push(next);
			display.setCurrent(next);
		}
	}

	public static void goForward(Alert alert, Displayable next) {
		screens.push(next);
		display.setCurrent(alert, next);
	}

	public static void loadAndShowCardStack(String url) {
		try {
			CardCanvas.get().setStack(new Sequence(
					getInputStreamReader(url)));
			CardCanvas.get().updateSettings();
			goForward(CardCanvas.get());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * This method return {@code InputStramReader} for specified url.
	 */
	private static InputStreamReader getInputStreamReader(String url) {
		try {
			FileConnection connection = (FileConnection) Connector.open(url,
					Connector.READ);
			return new InputStreamReader(connection.openDataInputStream(),
					"UTF8");
		} catch (Exception e) {
			return null;
		}
	}

	public interface PropertyChangeListener {
		public void propertyChanged(String propertyName, Object oldValue,
				Object newValue);
	}

	public static void addPropertyChangeListener(PropertyChangeListener pcl) {
		listeners.addElement(pcl);
	}

	public static void removePropertyChangeListener(PropertyChangeListener pcl) {
		listeners.removeElement(pcl);
	}

	/**
	 * Invokes when some property was changed.
	 */
	private static void firePropertyChange(String propertyName,
			Object oldValue, Object newValue) {
		Enumeration e = listeners.elements();
		while (e.hasMoreElements()) {
			((PropertyChangeListener) e.nextElement()).propertyChanged(
					propertyName, oldValue, newValue);
		}
	}

	public static int getInteger(String key) {
		return ((Integer) settings.get(key)).intValue();
	}
	
	public static Object getProperty(String key) {
		return settings.get(key);
	}

	public static Object getProperty(String key, Object fallback) {
		Object value = settings.get(key);
		return value != null ? value : fallback;
	}

	public static void setProperty(String key, Object newValue) {
		Object oldValue = settings.get(key);
		settings.put(key, newValue);
		firePropertyChange(key, oldValue, newValue);
	}

	private void loadDefaultProperties() {
		settings.put("wc4me.font.style", new Integer(1));
		settings.put("wc4me.font.size", new Integer(0));
		settings.put("wc4me.font.face", new Integer(0));
		settings.put("wc4me.canvas.orientation", new Integer(5));
		settings.put("wc4me.color.bkgcanvas", new Integer(0x000000));
	    settings.put("wc4me.color.bkgcard", new Integer(0x141414));
		settings.put("wc4me.color.font", new Integer(0xdbdbdb));
	}
}
